package org.ushio.speech_module.speech.chapter;

import org.ushio.speech_module.notification.NotificationService;

import org.ushio.speech_module.speech.dialoguebook.DialogueBookController;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestBody;
import org.ushio.common_module.config.annotation.Loggable;
import org.ushio.common_module.debounce.Debounce;
import org.ushio.common_module.util.response.ResponseResult;
import org.ushio.common_module.util.response.ResultCode;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 陈红
 */
@Slf4j
@RestController
@RequestMapping("/api/chapters")
public class ChapterController {

    private static final String CACHE_KEY_PREFIX = "chapter:";

    @Autowired
    private ChapterMapper chapterMapper;

    @Autowired
    private NotificationService notificationService;

    @Autowired
    @Qualifier("speechRedisTemplate")
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private DialogueBookController dialogueBookController;

    /**
     * 获取章节信息
     * @param id
     * @return ResponseResult
     */
    @GetMapping("/{id}")
    public ResponseResult<ChapterDTO> getChapterById(@PathVariable Long id) {
        // 尝试从 Redis 中获取章节信息
        String key = CACHE_KEY_PREFIX + id;
        Chapter chapter = (Chapter) redisTemplate.opsForValue().get(key);

        if (chapter == null) {
            // 如果 Redis 中没有，从数据库中获取
            chapter = chapterMapper.findById(id);
            if (chapter != null) {
                // 将章节信息存储到 Redis
                redisTemplate.opsForValue().set(key, chapter);
            } else {
                return ResponseResult.failed(ResultCode.NOT_FOUND.getCode(), "章节不存在");
            }
        }
        // 转换为 DTO
        ChapterDTO chapterDTO = new ChapterDTO(chapter.getChapterId(), chapter.getBookId(), chapter.getEtitle(), chapter.getTitle());
        return ResponseResult.success(chapterDTO);
    }

    /**
     * 获取所有章节信息
     * @return ResponseResult
     */
    @GetMapping
    public ResponseResult<List<ChapterDTO>> getAllChapters() {
        List<Chapter> chapters = chapterMapper.findAll();
        // 转换为 DTO 列表
        List<ChapterDTO> chapterDTOs = chapters.stream()
                .map(c -> new ChapterDTO(
                        c.getChapterId(),
                        c.getBookId(),
                        c.getEtitle(),
                        c.getTitle()))
                .collect(Collectors.toList());
        return ResponseResult.success(chapterDTOs);
    }

    /**
     * 获取指定书籍的所有章节信息
     * @param bookId
     * @return ResponseResult
     */
    @GetMapping("/byBookId")
    public ResponseResult<List<ChapterDTO>> getChaptersByBookId(@RequestParam Long bookId) {
        String key = CACHE_KEY_PREFIX + "book:" + bookId;
        List<Chapter> chapters = (List<Chapter>) redisTemplate.opsForValue().get(key);

        if (chapters == null) {
            chapters = chapterMapper.findByBookId(bookId);
            if (chapters != null && !chapters.isEmpty()) {
                redisTemplate.opsForValue().set(key, chapters);
            } else {
                return ResponseResult.failed(ResultCode.NOT_FOUND.getCode(), "该书籍没有章节");
            }
        }

        List<ChapterDTO> chapterDTOs = chapters.stream()
                .map(c -> new ChapterDTO(
                        c.getChapterId(),
                        c.getBookId(),
                        c.getEtitle(),
                        c.getTitle()))
                .collect(Collectors.toList());

        return ResponseResult.success(chapterDTOs);
    }

    /**
     * 创建章节
     * @param chapter
     * @return ResponseResult
     */
    @PostMapping
    @Debounce(interval = 500)
    @Loggable("新增章节")
    public ResponseResult<Integer> createChapter(@RequestBody Chapter chapter) {
        int result = chapterMapper.insert(chapter);
        if (result > 0) {
            // 将章节信息存储到 Redis
            String chapterKey = CACHE_KEY_PREFIX + chapter.getChapterId();
            redisTemplate.opsForValue().set(chapterKey, chapter);

            // 更新该章节所属书籍的章节列表缓存
            String bookKey = CACHE_KEY_PREFIX + "book:" + chapter.getBookId();
            // 先删除缓存中书籍的章节列表
            redisTemplate.delete(bookKey);

            // 重新加载该书籍的所有章节并更新缓存
            List<Chapter> chapters = chapterMapper.findByBookId(chapter.getBookId());
            redisTemplate.opsForValue().set(bookKey, chapters);

            String message = "《" + dialogueBookController.getBookById(chapter.getBookId()).getData().getTitle() + "》对话本新增了章节材料“" + chapter.getTitle() + "”噢!";
            notificationService.createNotification(message);

            return ResponseResult.success(result);
        } else {
            return ResponseResult.failed(ResultCode.INTERNAL_ERROR.getCode(), "创建章节失败");
        }
    }

    /**
     * 更新章节
     * @return ResponseResult
     */
    @PutMapping("/{id}")
    @Debounce(interval = 500)
    @Loggable("修改章节")
    public ResponseResult<Integer> updateChapter(@PathVariable Long id, @RequestBody Chapter chapter) {
        // 设置更新的章节ID
        chapter.setChapterId(id);

        // 先更新章节
        int result = chapterMapper.update(chapter);
        if (result > 0) {
            // 更新单个章节的缓存
            String chapterKey = CACHE_KEY_PREFIX + chapter.getChapterId();
            redisTemplate.opsForValue().set(chapterKey, chapter);

            // 更新该章节所属书籍的章节列表缓存
            String bookKey = CACHE_KEY_PREFIX + "book:" + chapter.getBookId();
            // 重新获取该书的章节列表
            List<Chapter> chapters = chapterMapper.findByBookId(chapter.getBookId());
            // 更新书籍的章节缓存
            redisTemplate.opsForValue().set(bookKey, chapters);

            return ResponseResult.success(result);
        } else {
            return ResponseResult.failed(ResultCode.INTERNAL_ERROR.getCode(), "更新章节失败");
        }
    }

    /**
     * 删除章节
     * @param id
     * @return ResponseResult
     */
    @DeleteMapping("/{id}")
    @Debounce(interval = 500)
    @Transactional
    @Loggable("删除章节")
    public ResponseResult<Integer> deleteChapter(@PathVariable Long id) {
        try {
            // 检查该章节是否有相关的句子
            int sentenceCount = chapterMapper.countSentencesByChapterId(id);

            if (sentenceCount > 0) {
                // 如果有相关的句子，返回错误提示
                return ResponseResult.failed(ResultCode.INTERNAL_ERROR.getCode(), "删除失败，请先删掉该章节的所有句子！");
            }

            // 在删除前查询章节信息，以获取书籍ID
            Chapter chapterToDelete = chapterMapper.findById(id);
            if (chapterToDelete == null) {
                return ResponseResult.failed(ResultCode.NOT_FOUND.getCode(), "章节不存在");
            }

            // 删除章节
            int result = chapterMapper.deleteById(id);

            if (result > 0) {
                // 删除 Redis 中的章节信息
                String chapterKey = CACHE_KEY_PREFIX + id;
                redisTemplate.delete(chapterKey);
                log.info("Deleted chapter cache: {}", chapterKey);

                // 获取该章节所属书籍的ID，并清除书籍的章节列表缓存
                Long bookId = chapterToDelete.getBookId();
                if (bookId != null) {
                    String bookKey = CACHE_KEY_PREFIX + "book:" + bookId;
                    redisTemplate.delete(bookKey);
                    log.info("Deleted book chapters cache: {}", bookKey);
                }

                return ResponseResult.success(result);
            } else {
                return ResponseResult.failed(ResultCode.NOT_FOUND.getCode(), "删除章节失败");
            }
        } catch (Exception e) {
            // 记录异常信息
            log.error("删除章节失败", e);
            return ResponseResult.failed(ResultCode.INTERNAL_ERROR.getCode(), "服务器内部错误");
        }
    }
}
